#include "StdAfx.h"
#include "XMLElement.h"

namespace xercescHelpingLibrary
{
	const string CXMLElement::EmptyString = ""; 

	CXMLElement::CXMLElement(void)
	{
		m_element = NULL;
		m_children = NULL;
	}

	CXMLElement::~CXMLElement(void)
	{
		// DON'T delete m_element, the parser handles deleting the element when the parser gets deleted.
	}

	//////////////////////////////////////////////////////////////////////////
	string CXMLElement::getName()
	{
		return XMLChToString(m_element->getNodeName());
	}

	bool CXMLElement::hasValue()
	{
		DOMText* domTextNode = getTextContent();
		return (domTextNode!=NULL);
	}

	string CXMLElement::getStringValue()
	{
		DOMText* domTextNode = getTextContent();
		if (domTextNode==NULL)
			return EmptyString;

		return XMLChToString(domTextNode->getData());
	}

	double CXMLElement::getDoubleValue()
	{
		return StringToDouble(getStringValue());
	}

	int CXMLElement::getIntValue()
	{
		return StringToInt(getStringValue());
	}

	//////////////////////////////////////////////////////////////////////////

	vector<CXMLElement*>* CXMLElement::getChildElements()
	{
		if (m_children==NULL)
		{
			m_children = new vector<CXMLElement*>();
			if (m_element->hasChildNodes())
			{
				DOMNodeList* children = m_element->getChildNodes();
				for(unsigned int i=0; i<children->getLength()-1; i++)
				{
					DOMNode* node = children->item(i);
					if( !node->getNodeType() || node->getNodeType() != DOMNode::ELEMENT_NODE )
						continue;
					DOMElement* element = dynamic_cast< xercesc::DOMElement* >( node );
					m_children->push_back(CreateElement(element));
				}
			}
		}

		return m_children;
	}

	CXMLElement* CXMLElement::getElementByAttribute(string attributeName, string attributeValue)
	{
		XMLCh* xAttributeName = new XMLCh[attributeName.length() + 1];
		XMLCh* xAttributeValue = new XMLCh[attributeValue.length() + 1];
		XMLString::transcode(attributeName.c_str(), xAttributeName, attributeName.length());
		XMLString::transcode(attributeValue.c_str(), xAttributeValue, attributeValue.length());

		CXMLElement* xmlElement = getElementByAttribute(m_element, xAttributeName, xAttributeValue);

		delete xAttributeName;
		delete xAttributeValue;

		return xmlElement;
	}

	tuple<string, string> getAttributes()
	{
		// TODO: more work is required.
		return tuple<string, string>();
	}

	string CXMLElement::getAttributeValue( string attributeName ) 
	{
		XMLCh* xtext = new XMLCh[attributeName.length() + 1];
		XMLString::transcode(attributeName.c_str(), xtext, attributeName.length());
		const XMLCh* val = m_element->getAttribute(xtext);
		delete xtext;
		return XMLChToString(val);
	}

	//////////////////////////////////////////////////////////////////////////

	DOMText* CXMLElement::getTextContent()
	{
		return dynamic_cast<DOMText*>(m_element->getFirstChild());
	}
	
	double CXMLElement::StringToDouble(string s)
	{
		istringstream instr(s);
		double x;
		instr >> x;
		return x;
	}

	int CXMLElement::StringToInt(string s)
	{
		istringstream instr(s);
		int x;
		instr >> x;
		return x;
	}

	string CXMLElement::XMLChToString(const XMLCh* arr)
	{
		if (arr==NULL) return EmptyString;
		char* s = XMLString::transcode(arr);
		string r(s);
		XMLString::release(&s);
		return r;
	}

	//////////////////////////////////////////////////////////////////////////

	CXMLElement* CXMLElement::CreateElement(DOMElement* element)
	{
		if (element==NULL) return NULL;

		CXMLElement* newObject = new CXMLElement();
		newObject->m_element = element;
		return newObject;
	}

	bool CXMLElement::CheckAttribute(DOMElement* element, XMLCh* xAttributeName, XMLCh* xAttributeValue)
	{
		if (!element->hasAttribute(xAttributeName)) return false;
		const XMLCh* val = element->getAttribute(xAttributeName);
		bool result = (XMLString::compareString(xAttributeValue, val)==0);

		return result;
	}

	CXMLElement* CXMLElement::getElementByAttribute(DOMElement* element, XMLCh* xAttributeName, XMLCh* xAttributeValue)
	{
		if ( CheckAttribute(element, xAttributeName, xAttributeValue) )
			return CreateElement(element);

		if (!element->hasChildNodes()) return NULL;

		DOMNodeList* children = element->getChildNodes();
		for(unsigned int i=0; i<children->getLength()-1; i++)
		{
			DOMNode* node = children->item(i);
			if( !node->getNodeType() || node->getNodeType() != DOMNode::ELEMENT_NODE )
				continue;

			DOMElement* element = dynamic_cast< xercesc::DOMElement* >( node );
			CXMLElement* xmlElement = getElementByAttribute(element, xAttributeName, xAttributeValue);
			if (xmlElement) return xmlElement;
		}

		return NULL;
	}


	


	

}